<!DOCTYPE html>
<html>
    <head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
    <meta content="yes" name="apple-mobile-web-app-capable">
    <meta content="black" name="apple-mobile-web-app-status-bar-style">
    <meta content="telephone=no" name="format-detection">
    <meta content="email=no" name="format-detection">
    <meta content="portrait" name="x5-orientation">
    <style type="text/css">
        .hide {
            display: none!important;
        }
        .red {
            color: red;
        }
        .green {
            color: green;
        }
        .container {
            margin: 0 20px;
        }
        .url {
            word-wrap: break-word;
            word-break: break-all;
        }
        body {
            font-family: "Helvetica Neue", Helvetica, STHeiTi, sans-serif;
        }
    </style>
    <title>网络接口检测工具</title>
</head>

<body>
    <div class="container">
        <div>wechat.jinlb.cn 域名解析成功</div>
        <div class="js_run_result">
        </div>
        <div class="green js_end hide">页面检测已完成，感谢您的配合，请截图发送给客服，谢谢</div>
    </div>
    <!-- 页面通用模块 -->

    <script type="text/javascript">
    (function() {
        /**
         * Ajax问题参考：参考：http://javascript.ruanyifeng.com/bom/ajax.html
         * status 0 的问题原因：
         * url不存在
         * url不可达
         * 发送了跨域请求
         * 数据格式错
         * ajax在完成之前请求已经被取消（ajax请求没有发出），由于，例如：页面已经跳转或跳转太快、浏览器输入新的url、按钮立即新的点击等
         * @type {Array}
         */
        var Log = [];
        window.onerror = function(message, source, lineno, colno, error) {
            Log.push("window.onerror: " + message + " " + source);
        };
        /**
         * 模拟jQuery - querySelectorAll兼容性：A2.1 I3.2
         * @param  {[type]} selector [description]
         * @return {[type]}          [description]
         */
        var $ = function(selector) {
            return new $.fn.init(selector);
        };
        $.fn = {
            init: function(selector) {
                if (selector.indexOf("#") === 0) {
                    this.nodeList = [document.getElementById(selector.slice(1))];
                } else {
                    this.nodeList = document.querySelectorAll(selector);
                }
                return this;
            },
            each: function(callback) {
                var nodeList = this.nodeList;
                for (var i = 0; i < nodeList.length; i++) {
                    callback(nodeList[i], i, nodeList);
                }
            },
            append: function(text) {
                this.each(function(elem, i) {
                    var frag = document.createElement("div");
                    frag.innerHTML = text;
                    elem && elem.appendChild(frag);
                });
                return this;
            },
            html: function(text) {
                this.each(function(elem, i) {
                    elem.innerHTML = text;
                });
                return this;
            },
            removeClass: function(name) {
                this.each(function(elem, i) {
                    var className = elem.className,
                        classRE = new RegExp('(^|\\s)' + name + '(\\s|$)');
                    var newName = className.replace(classRE, "");
                    elem.className = newName;
                });
                return this;
            },
            addClass: function(name) {
                this.each(function(elem, i) {
                    var className = elem.className;
                    className += " " + name;
                    elem.className = className;
                });
                return this;
            }
        };
        $.fn.init.prototype = $.fn;
        /**
         * ajax 请求 - XMLHttpRequest 兼容性：A3+ I5.1
         * @param  {[type]} options [description]
         * @return {[type]}         [description]
         */
        var _waitList = [];
        $.ajax = function(options) {
            Log = [];
            var xhr = new XMLHttpRequest();
            // 指定通信过程中状态改变时的回调函数
            xhr.onreadystatechange = function() {
                // 通信成功时，状态值为4
                if (xhr.readyState === 4) {
                    // 如果是 html，直接返回就好了
                    if(options.type === 'html') {
                        options.success(xhr.responseText);
                        var f = _waitList.shift();
                        typeof f === 'function' && f();
                        return;
                    }

                    if (xhr.status === 200) {
                        options.success(xhr.responseText);
                        var f = _waitList.shift();
                        typeof f === 'function' && f();
                    } else {
                        Log.push("readyState：4；status异常: " + xhr.status);
                    }
                } else {
                    Log.push("readyState状态值：" + xhr.readyState);
                }
            };
            xhr.onloadstart = function() {
                Log.push("onloadstart: 请求已发出");
            };
            xhr.onprogress = function() {
                Log.push("onprogress: 正在发送和加载数据");
            };
            xhr.onload = function() {
                Log.push("onload: 请求成功完成");
            };
            xhr.onloadend = function() {
                Log.push("onloadend: 请求完成，不管成果或失败");
            };
            // 终态
            xhr.onabort = function() {
                Log.push("onabort: 请求被中止");
                options.error(xhr, "abort", xhr.status);
                $container.$checkEnd.removeClass("hide");
            };
            xhr.ontimeout = function() {
                Log.push("ontimeout: 用户指定的时限到期，请求还未完成");
                options.error(xhr, "timeout", xhr.status);
                $container.$checkEnd.removeClass("hide");
            };
            xhr.onerror = function(e) {
                if(options.type === 'html') {
                    return;
                }
                Log.push("onerror: 请求失败");
                options.error(xhr, xhr.statusText, xhr.status);
                $container.$checkEnd.removeClass("hide");
            };
            xhr.timeout = 30 * 1000; // 30秒
            // xhr.withCredentials = true; // 允许携带cookie
            xhr.open('GET', options.url, true); // open方式用于指定HTTP动词、请求的网址、是否异步
            xhr.send(null); // 发送HTTP请求
        };
        // 异步拉取脚本
        $.loadScript = function(options) {
            var script = document.createElement("script");
            script.src = options.url;
            script.crossorigin = "anonymous";
            window.onerror = function(message, source, lineno, colno, error) {
                _waitList = [];
                options.error("脚本执行异常: " + message + " " + source);
                $container.$checkEnd.removeClass("hide");
            };
            script.onload = function() {
                options.success();
                var f = _waitList.shift();
                typeof f === 'function' && f();
            };
            document.body.appendChild(script);
        };
        // 异步拉取IMAGE
        $.loadImage = function(options) {
            var img = new Image(0, 0);
            img.onerror = img.onabort = function() {
                options.error();
                var f = _waitList.shift();
                typeof f === 'function' && f();
                $container.$checkEnd.removeClass("hide");
            };
            img.onload = function() {
                options.success();
                var f = _waitList.shift();
                typeof f === 'function' && f();
            };
            img.src = options.src;
        };
        /**
         * 支持简单链式调用.then().then()
         * @param  {[type]} options [description]
         * @return {[type]}         [description]
         */
        var Promise = function(callback) {
            this.then = function(f) {
                _waitList.push(f);
                return this;
            };
            setTimeout(function() {
                callback();
            }, 10);
        };

        var checkJS = function(key, url, name, type) {
            if(!key) {
                return function() {}
            }
            return function() {
                var from_date =  (new Date()).getTime()
                $.ajax({
                    url: url,
                    type,
                    error: function(xhr, statusText, status) {
                        const to_date =  (new Date()).getTime();
                        const msg = "检测失败 " + key + " ，耗时：" + (to_date - from_date)  + "ms" + '<br/>'
                                  + "status: " + status + ", statusText: " + statusText;
                        const logs = "<br/>logs信息：<br/>" + Log.join("<br/>");
                        $container.$runResult.append('<div class="red">'+ msg + logs +'</div>');
                    },
                    success: function() {
                        const to_date =  (new Date()).getTime();
                        const msg = `检测项目 ${key}${name}, 耗时：${(to_date - from_date)}ms`;
                        $container.$runResult.append(msg);
                    }
                })
            }
        }

        var $container = $(".container");
        $container.$runResult = $(".js_run_result");
        $container.$checkEnd = $(".js_end");

        var JLB_IMG = "https://cdn2.jinlb.cn/pic/c0/c1/c0c1ce6d86eaf0278769a4a32beae0d2.png"

        var checkList = {
            pay_html:'https://wechat.jinlb.cn/Pay.html',
            baidu_html: 'https://www.baidu.com',
            react_js:'https://cdn2.jinlb.cn/web/weixin/js/react.min.js',
            jlb_js: 'https://cdn2.jinlb.cn/web/weixin/v2018-11-6/PickUpDetailv1.min.js',
            jlb_css: 'https://cdn2.jinlb.cn/web/weixin/v2018-11-6/PickUpDetailv1.min.css',
            raven_js: 'https://cdn2.jinlb.cn/web/weixin/js/raven.min.js',
        }

        var promise1 = checkJS('baidu_html', checkList.baidu_html, '@baidu.com', 'html');
        var promise2 = checkJS('pay_html', checkList.pay_html, '@wechat.jinlb.cn', 'html');
        var promise3 = checkJS('react_js', checkList.react_js, '@cdn2.jinlb.cn');
        var promise4 = checkJS('jlb_js', checkList.jlb_js, '@cdn2.jinlb.cn');
        var promise5 = checkJS('jlb_css', checkList.jlb_css, '@cdn2.jinlb.cn');

        new Promise(function() {
                var from_date =  (new Date()).getTime()
                $.loadImage({
                    src: JLB_IMG,
                    error: function(xhr, statusText, status) {
                        var to_date =  (new Date()).getTime();
                        var msg = "检测失败 jlb_img @ cdn2.jinlb.cn，耗时：" + (to_date - from_date)  + "ms";
                        $container.$runResult.append('<div class="red">'+ msg +'</div>');
                    },
                    success: function() {
                        var to_date =  (new Date()).getTime();
                        var msg = "检测项目 jlb_img@cdn2.jinlb.cn，耗时：" + (to_date - from_date)  + "ms";
                        $container.$runResult.append('<div>' + msg + '</div>');
                    }
                })
            })
            .then(promise1)
            .then(promise2)
            .then(promise3)
            .then(promise4)
            .then(promise5)
            .then(function() {
                var canFetch = !!self.fetch;
                $container.$runResult.append('fetch可用性: ' + canFetch);

                if(!canFetch) {
                    $container.$checkEnd.removeClass("hide");
                    return;
                }
                
                var code
                try {
                   code = window.location.href.split('code=')[1].split('&')[0];
                } catch (e) {
                   code = 123 
                }
                var url1 = `https://api.jinlb.cn/weixin/external/auth/login?code=${code}`;

                var from_date =  (new Date()).getTime()
                $container.$runResult.append(`<div class="url">开始检测接口 ${url1}， 请等待...</div>`);
                
                return fetch(url1)
                .then(function(response) {
                    var to_date =  (new Date()).getTime();
                    var msg = "fetch login 成功，耗时：" + (to_date - from_date)  + "ms";
                    $container.$runResult.append('<div>' + msg + '</div>');
                    return response.json();
                })
                .then(function(myJson) {
                    const str =  JSON.stringify(myJson)
                    $container.$runResult.append(`<div class="url">${str}</div>`);
                    $container.$checkEnd.removeClass("hide");
                }).catch(e => {
                    $container.$runResult.append(e);
                });
            });
    })();
    </script>
    <noscript>&lt;div class="red"&gt;悲剧，你的浏览器竟然禁止了JavaScript！&lt;/div&gt;</noscript>
</body></html>
